/*
	Filename	:	hikeguts.h
	Author		:	Ray E. Bornert II
	Date		:	2003-JAN-15
	Copyright	:	(c) 2003 RealTimeGaming

	History		:
*/

//////////
// GATE //
//////////
#ifndef _HIKEGUTS_H_
#define _HIKEGUTS_H_

/////////////
// FORWARD //
/////////////
class HikeSlotGuts;

//////////////
// INCLUDES //
//////////////
#include "slotguts.h"

/////////////
// DEFINES //
/////////////

//declare a type for the random number generator
typedef unsigned long int randtype;

#define MAXDIEFACE (6)


////////////
// OBJECT //
////////////
class HikeSlotGuts	:	public SlotGuts
{
    enum SUBGAMEIDX
    {
        SGIDX_NDIEFACESCOLLECTED			=	 0,
		SGIDX_SPIN_1DIEFACE					=	 1,
		SGIDX_SPIN16DIEFACE					=	16,
		SGIDX_GAMESTATE						=	17,
		SGIDX_NCREDITSBET					=	18,
		SGIDX_NPAYOUTCENTICREDITS			=	19,
		SGIDX_NBUYOUTCENTICREDITS			=	20,
		SGIDX_NUNPAIDMILLICREDITS			=	21
    };

	enum HikeMessage
	{
		HikeNextGame,	//player wants to begin a game
		HikeFreeGame,	//player wants a free game
		HikeNextSpin,	//player wants another spin
		HikeSellGame	//player wants to sell game
	};

	enum HikeGameState
	{
		HikeGameState__RESET			,	//the game start state
		HikeGameState__WAIT_NEXTGAME	,	//waiting for at least 1 credit wager
		HikeGameState__WAIT_SPINORSELL	,	//waiting for spin or sell
		HikeGameState__SELLGAME			,	//buy this game from the player
		HikeGameState__GAMEOVER			,	//game is finished
		HikeGameState__MAXGAMESTATE			//placeholder
	};

/////////////
// MEMBERS //
/////////////
private://MEMBERS

	//STATIC
	static const int	m_theGutsID;
	static const int	m_maximumDieface;
	static const int	m_maximumPayline;
	static const int	m_maximumHistory;
	static const int	m_maximumCredits;

	static const int	m_PayTable6Stop[18][8];
	static const int	m_ExpectedPayout6Stop[720];

	/////////////////////////////////////////////////
	//THE INTERNAL COLLECTION COUNTS
	int					m_nCollected[MAXDIEFACE+1];
	/////////////////////////////////////////////////

public:	//MEMBERS

/////////////
// METHODS //
/////////////

private://METHODS

	//STATIC
	static int			IsHistoryValid	( int history );
	static int			IsPaylineValid	( int payline );
	static int			IsDiefaceValid	( int dieface );
	static randtype		RollDie			( unsigned nFaces );

	//IS
	int		IsCollectionValid		();
	int		IsCollectionEmpty		();
	int		IsCollectionComplete	();
	int		IsCollectionIncomplete	();
	int		IsCollectionInProgress	();
	int		IsNCreditsBetValid		( int nCreditsBet );
	int		IsPayoutValid			( int payout );
	int		IsNextGameAllowed		();
	int		IsFreeGameAllowed		();
	int		IsNextRollAllowed		();
	int		IsSellGameAllowed		();

	//GET/SET
	HikeGameState	SetGameState	( HikeGameState state );
	HikeGameState	GetGameState	();
	int		SetNDiefacesCollected	( int nDiefacesCollected );
	int		GetNDiefacesCollected	();
	int		SetNCreditsBet			( int nCreditsBet );
	int		GetNCreditsBet			();
	int		SetPaylineDieface		( int payline, int dieface );
	int		GetPaylineDieface		( int payline );
	int		SetNUnpaidMilliCredits	( int nUnpaidMilliCredits );
	int		GetNUnpaidMilliCredits	();
	int		SetNPayoutCentiCredits	( int nPayoutCentiCredits );
	int		GetNPayoutCentiCredits	();
	int		SetNBuyoutCentiCredits	( int nBuyoutCentiCredits );
	int		GetNBuyoutCentiCredits	();

	//READ ONLY CALCULATION ROUTINES
	int		CalcPayout				( int dieface, int payline );
	int		CalcBuyout				();
	int		CalcHistoryIndex		();		
	int		CalcExpectedPayout		( int historyIndex );
	int		CalcNDiefacesCollected	();

	//READ/WRITE GAME STATE ROUTINES
	void	DoZeroCollectionCounts	();
	void	DoLoadCollectionCounts	();
	void	DoResetGameState		();
	void	DoCollectDieface		( randtype dieface );
	void	DoCollectionIncomplete	();
	void	DoCollectionComplete	();
	void	DoPayout				( int nCentiCredits );

	//PLAYER REQUEST ENTRY POINTS
	void	HandleNextGame			( int nCreditsBet );
	void	HandleNextRoll			();
	void	HandleFreeGame			( int nCreditBet );
	void	HandleSellGame			();


public:	//METHODS

	//VIRTUAL
	/*/////////////////////////////////////////////////////////
	The main entry points called by SlotConn and SlotGuts
	/////////////////////////////////////////////////////////*/
	virtual	bool8		isValidGuts		();	
	//virtual	bool8		isGameComplete	();
	virtual bool8		isValidBet		( uint8 bet );

	virtual	SlotSpin*	spin
	(
		uint8 bet,			//the players bet in credits
		int32 mbbet,		//multibank bet in cents
		uint8 *lines,		//the array of bet lines
		uint8 lineCount,	//the number of lines bet
		uint8 bonusGame		//the bonus game id
	);

	virtual	void		playBonusGame
	(
		uint8 bonusGameType,	//message type from the client
		int32 bonusDataCount,	//number of longs in message
		int32 *bonusData		//list of longs in message
	);

	virtual void		completeSpin
	(
		
	){}; //Implemented by JB 1/24 to make compile
	//////////////////////////////////////////////////////////

	HikeSlotGuts();
	virtual ~HikeSlotGuts();
};


/*///////////////////////////////////
	GETGAMESTATE
	retrieve the present game state
///////////////////////////////////*/
inline HikeSlotGuts::HikeGameState
HikeSlotGuts::GetGameState()
{
	HikeGameState gameState = (HikeGameState)m_subGame->getData( SGIDX_GAMESTATE );
	return gameState;
}

/*///////////////////////////////////
	SETGAMESTATE
	remember the present game state
///////////////////////////////////*/
inline HikeSlotGuts::HikeGameState
HikeSlotGuts::SetGameState( HikeGameState gameState )
{
	m_subGame->update( SGIDX_GAMESTATE, gameState );
	return GetGameState();
}

/*///////////////////////////////////////////////////
	GETNDIEFACESCOLLECTED
	retrieve the total number of diefaces collected
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetNDiefacesCollected()
{
	int nCollected = m_subGame->getData( SGIDX_NDIEFACESCOLLECTED );
	return nCollected;
}

/*///////////////////////////////////////////////////
	SETNDIEFACESCOLLECTED
	remember the total number of diefaces collected
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetNDiefacesCollected( int nDiefacesCollected )
{
	m_subGame->update( SGIDX_NDIEFACESCOLLECTED, nDiefacesCollected );
	return GetNDiefacesCollected();
}

/*///////////////////////////////////////////////////
	SETNCREDITSBET
	remember the number of credits bet on this game
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetNCreditsBet( int nCreditsBet )
{
	m_subGame->update( SGIDX_NCREDITSBET, nCreditsBet );
	return GetNCreditsBet();
}

/*///////////////////////////////////////////////////
	GETNCREDITSBET
	retrieve the number of credits bet on this game
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetNCreditsBet()
{
	int nCreditsBet = m_subGame->getData( SGIDX_NCREDITSBET );
	return nCreditsBet;
}

/*///////////////////////////////////////////////////
	SETPAYLINEDIEFACE
	remember the dieface for the given payline
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetPaylineDieface( int payline, int dieface )
{
	m_subGame->update( payline, dieface );
	return GetPaylineDieface( payline );
}

/*///////////////////////////////////////////////////
	GETPAYLINEDIEFACE
	retrieve the dieface for the given payline
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetPaylineDieface( int payline )
{
	int dieface = m_subGame->getData( payline );
	return dieface;
}

/*///////////////////////////////////////////////////
	GETNUNPAIDMILLICREDITS
	retrieve the number of unpaid centi credits
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetNUnpaidMilliCredits()
{
	int nUnpaidMilliCredits = m_subGame->getData( SGIDX_NUNPAIDMILLICREDITS );
	return nUnpaidMilliCredits;
}

/*///////////////////////////////////////////////////
	SETNUNPAIDMILLICREDITS
	remember the number of unpaid milli credits
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetNUnpaidMilliCredits( int nUnpaidMilliCredits )
{
	m_subGame->update( SGIDX_NUNPAIDMILLICREDITS, nUnpaidMilliCredits );
	return GetNUnpaidMilliCredits();
}

/*///////////////////////////////////////////////////
	GETNPAYOUTCENTICREDITS
	retrieve the number of payout centi credits
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetNPayoutCentiCredits()
{
	int nPayoutCredits = m_subGame->getData( SGIDX_NPAYOUTCENTICREDITS );
	return nPayoutCredits;
}

/*///////////////////////////////////////////////////
	SETNPAYOUTCENTICREDITS
	remember the number of payout centi credits
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetNPayoutCentiCredits( int nPayoutCentiCredits )
{
	m_subGame->update( SGIDX_NPAYOUTCENTICREDITS, nPayoutCentiCredits );
	return GetNPayoutCentiCredits();
}

/*///////////////////////////////////////////////////
	SETNBUYOUTCENTICREDITS
	retrieve the number of buyout centi credits offered
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::GetNBuyoutCentiCredits()
{
	int nBuyoutCentiCredits = m_subGame->getData( SGIDX_NBUYOUTCENTICREDITS );
	return nBuyoutCentiCredits;
}

/*///////////////////////////////////////////////////
	SETNBUYOUTCENTICREDITS
	remember the number of buyout centi credits offered
///////////////////////////////////////////////////*/
inline int
HikeSlotGuts::SetNBuyoutCentiCredits( int nBuyoutCentiCredits )
{
	m_subGame->update( SGIDX_NBUYOUTCENTICREDITS, nBuyoutCentiCredits );
	return GetNBuyoutCentiCredits();
}

#endif
